package com.nbsaas.nbmall.promote.rest.resource;

import com.nbsaas.nbmall.customer.data.dao.CustomerDao;
import com.nbsaas.nbmall.customer.data.entity.Customer;
import com.nbsaas.nbmall.promote.api.apis.CouponApi;
import com.nbsaas.nbmall.promote.api.domain.list.CouponList;
import com.nbsaas.nbmall.promote.api.domain.page.CouponPage;
import com.nbsaas.nbmall.promote.api.domain.request.*;
import com.nbsaas.nbmall.promote.api.domain.response.CouponResponse;
import com.nbsaas.nbmall.promote.api.domain.simple.CouponSimple;
import com.nbsaas.nbmall.promote.data.dao.CouponDao;
import com.nbsaas.nbmall.promote.data.entity.Coupon;
import com.nbsaas.nbmall.promote.data.entity.CouponRule;
import com.nbsaas.nbmall.promote.data.enums.CouponCatalog;
import com.nbsaas.nbmall.promote.data.enums.CouponState;
import com.nbsaas.nbmall.promote.data.enums.ExpireType;
import com.nbsaas.nbmall.promote.rest.convert.CouponResponseConvert;
import com.nbsaas.nbmall.promote.rest.convert.CouponSimpleConvert;
import com.haoxuer.bigworld.tenant.data.entity.Tenant;
import com.haoxuer.discover.config.utils.ConverResourceUtils;
import com.haoxuer.discover.data.page.Filter;
import com.haoxuer.discover.data.page.Order;
import com.haoxuer.discover.data.page.Page;
import com.haoxuer.discover.data.page.Pageable;
import com.haoxuer.discover.data.utils.FilterUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.haoxuer.bigworld.member.rest.conver.PageableConver;
import com.haoxuer.bigworld.tenant.util.TenantBeanUtils;
import com.nbsaas.nbmall.shop.data.dao.ShopDao;
import com.haoxuer.bigworld.member.data.dao.TenantUserDao;
import com.nbsaas.nbmall.promote.data.dao.CouponRuleDao;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Transactional
@Component
public class CouponResource implements CouponApi {

    @Autowired
    private CouponDao dataDao;

    @Autowired
    private ShopDao shopDao;
    @Autowired
    private TenantUserDao tenantUserDao;
    @Autowired
    private CouponRuleDao couponRuleDao;

    @Autowired
    private CustomerDao customerDao;

    @Override
    public CouponResponse create(CouponDataRequest request) {
        CouponResponse result = new CouponResponse();

        if (request.getCouponRule() == null) {
            result.setCode(501);
            result.setMsg("无效优惠券");
            return result;
        }
        CouponRule rule = couponRuleDao.findById(request.getCouponRule());
        if (rule == null) {
            result.setCode(502);
            result.setMsg("无效优惠券");
            return result;
        }

        Integer limitNum = rule.getLimitNum();
        if (limitNum == null) {
            limitNum = 0;
        }
        if (limitNum != 0) {
            Long num = dataDao.handle("count", "id",
                    Filter.eq("tenantUser.id", request.getUser()),
                    Filter.eq("couponRule.id", request.getCouponRule()));
            if (num == null) {
                num = 0L;
            }
            if (num >= limitNum) {
                result.setCode(503);
                result.setMsg("已经领取过了");
                return result;
            }
        }
        Long num = dataDao.handle("count", "id", Filter.eq("couponRule.id", request.getCouponRule()));
        if (num == null) {
            num = 0L;
        }
        if (num >= rule.getStock()) {
            result.setCode(505);
            result.setMsg("已领完了");
            return result;
        }

        Coupon bean = new Coupon();


        bean.setTenant(Tenant.fromId(request.getTenant()));
        if (request.getTenantUser() != null) {
            bean.setTenantUser(tenantUserDao.findById(request.getTenantUser()));
        }
        bean.setCouponRule(rule);
        if (rule.getExpireType() == null) {
            rule.setExpireType(ExpireType.date);
        }
        if (rule.getExpireType() == ExpireType.date) {
            bean.setUseBeginTime(rule.getUseBeginTime());
            bean.setUseEndTime(rule.getUseEndTime());
        } else {
            bean.setUseBeginTime(new Date());
            Calendar calendar = Calendar.getInstance();
            if (rule.getUseDay() == null) {
                rule.setUseDay(1);
            }
            calendar.add(Calendar.DAY_OF_MONTH, rule.getUseDay());
            bean.setUseEndTime(calendar.getTime());

        }
        bean.setMoney(rule.getMoney());
        bean.setShop(rule.getShop());
        CouponCatalog catalog = rule.getCouponCatalog();
        if (catalog == null) {
            catalog = CouponCatalog.coupon;
        }
        bean.setCouponCatalog(catalog);
        bean.setCouponState(CouponState.init);
        dataDao.save(bean);
        result = new CouponResponseConvert().conver(bean);

        num++;
        rule.setSendNum(num);

        Customer customer = customerDao.findById(request.getUser());
        if (customer != null) {
            Long userNum = dataDao.handle("count", "id", Filter.eq("tenantUser.id", request.getUser()));
            if (userNum == null) {
                userNum = 0L;
            }
            customer.setCouponNum(userNum);
        }
        return result;
    }

    @Override
    public CouponResponse update(CouponDataRequest request) {
        CouponResponse result = new CouponResponse();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("无效id");
            return result;
        }
        Coupon bean = dataDao.findById(request.getId());
        if (bean == null) {
            result.setCode(502);
            result.setMsg("无效id");
            return result;
        }
        handleData(request, bean);
        result = new CouponResponseConvert().conver(bean);
        return result;
    }

    private void handleData(CouponDataRequest request, Coupon bean) {
       TenantBeanUtils.copyProperties(request,bean);
           if(request.getTenantUser()!=null){
              bean.setTenantUser(tenantUserDao.findById(request.getTenantUser()));
           }
           if(request.getShop()!=null){
              bean.setShop(shopDao.findById(request.getShop()));
           }
           if(request.getCouponRule()!=null){
              bean.setCouponRule(couponRuleDao.findById(request.getCouponRule()));
           }

    }

    @Override
    public CouponResponse delete(CouponDataRequest request) {
        CouponResponse result = new CouponResponse();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("无效id");
            return result;
        }
        dataDao.deleteById(request.getTenant(),request.getId());
        return result;
    }

    @Override
    public CouponResponse view(CouponDataRequest request) {
        CouponResponse result=new CouponResponse();
        Coupon bean = dataDao.findById(request.getTenant(), request.getId());
        if (bean==null){
            result.setCode(1000);
            result.setMsg("无效id");
            return result;
        }
        result=new CouponResponseConvert().conver(bean);
        return result;
    }
    @Override
    public CouponList list(CouponSearchRequest request) {
        CouponList result = new CouponList();

        List<Filter> filters = new ArrayList<>();
        filters.add(Filter.eq("tenant.id", request.getTenant()));
        filters.addAll(FilterUtils.getFilters(request));
        List<Order> orders = new ArrayList<>();
        if ("asc".equals(request.getSortMethod())){
           orders.add(Order.asc(""+request.getSortField()));
        }
        else if ("desc".equals(request.getSortMethod())){
           orders.add(Order.desc(""+request.getSortField()));
        }else{
           orders.add(Order.desc("id"));
        }
        List<Coupon> organizations = dataDao.list(0, request.getSize(), filters, orders);

        CouponSimpleConvert convert=new CouponSimpleConvert();
        ConverResourceUtils.converList(result, organizations,convert);
        return result;
    }

    @Override
    public CouponPage search(CouponSearchRequest request) {
        CouponPage result=new CouponPage();
        Pageable pageable = new PageableConver().conver(request);
        pageable.getFilters().addAll(FilterUtils.getFilters(request));
        pageable.getFilters().add(Filter.eq("tenant.id", request.getTenant()));
        if ("asc".equals(request.getSortMethod())){
            pageable.getOrders().add(Order.asc(""+request.getSortField()));
        }
        else if ("desc".equals(request.getSortMethod())){
            pageable.getOrders().add(Order.desc(""+request.getSortField()));
        }else{
            pageable.getOrders().add(Order.desc("id"));
        }
        Page<Coupon> page=dataDao.page(pageable);

        CouponSimpleConvert convert=new CouponSimpleConvert();
        ConverResourceUtils.converPage(result,page,convert);
        return result;
    }

    @Override
    public List<CouponSimple> platform(Long user) {
        List<CouponSimple> result = new ArrayList<>();

        List<Filter> filters = new ArrayList<>();
        filters.add(Filter.eq("tenantUser.id", user));
        filters.add(Filter.eq("couponState", CouponState.init));
        filters.add(Filter.le("useBeginTime", new Date()));
        filters.add(Filter.ge("useEndTime", new Date()));
        filters.add(Filter.isNull("shop.id"));

        List<Order> orders = new ArrayList<>();
        orders.add(Order.desc("money"));


        List<Coupon> dishCoupons = dataDao.list(0, 50, filters, orders);
        if (dishCoupons != null && dishCoupons.size() > 0) {
            CouponSimpleConvert convert = new CouponSimpleConvert();
            List<CouponSimple> temps = ConverResourceUtils.converList(dishCoupons, convert);
            result.addAll(temps);
        }
        return result;    }
}
